package com.github.md11235.ideaproofofwork.cfiletracker

import com.intellij.openapi.editor.event.DocumentEvent
import com.intellij.openapi.editor.event.DocumentListener
import com.intellij.openapi.editor.event.EditorFactoryEvent
import com.intellij.openapi.editor.event.EditorFactoryListener
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.diagnostic.Logger
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import com.github.md11235.ideaproofofwork.cfiletracker.CFileTrackerUI
import com.intellij.openapi.util.io.toNioPathOrNull
import kotlin.io.path.pathString

class CFileChangeListener : EditorFactoryListener {

    private val log = Logger.getInstance(CFileChangeListener::class.java)

    override fun editorCreated(event: EditorFactoryEvent) {
        val editor = event.editor
        val document = editor.document
        val file = FileDocumentManager.getInstance().getFile(document)

        if (file == null || file.extension != "c") return

        val project = ProjectManager.getInstance().openProjects.firstOrNull() ?: return
//        val repo = findGitRepositoryForFile(project, file) ?: return
//
        val logFile = file.path.toNioPathOrNull()?.resolve("c_file_tracker.log")
        log.info("Tracking ${file.path} using ${logFile}") // in repo ${repo.root.name}")

        document.addDocumentListener(object : DocumentListener {
            override fun documentChanged(event: DocumentEvent) {
                val newText = event.newFragment.toString()
                val oldText = event.oldFragment.toString()

                val timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
                val msg = when {
                    newText.isNotEmpty() && oldText.isEmpty() ->
                        "[$timestamp] INSERT in ${file.path}: \"$newText\""
                    newText.isEmpty() && oldText.isNotEmpty() ->
                        "[$timestamp] DELETE in ${file.path}: \"$oldText\""
                    else ->
                        "[$timestamp] MODIFY in ${file.path}: \"$oldText\" → \"$newText\""
                }

                CFileTrackerUI.addEvent(msg)
                appendToLogFile(Path.of(logFile.toString()), msg)
            }
        })
    }

//    private fun findGitRepositoryForFile(project: com.intellij.openapi.project.Project, file: VirtualFile): GitRepository? {
//        val mgr = GitRepositoryManager.getInstance(project)
//        return mgr.repositories.find { repo -> file.path.startsWith(repo.root.path) }
//    }

    private fun appendToLogFile(path: Path, message: String) {
        try {
            Files.writeString(
                path,
                message + System.lineSeparator(),
                StandardOpenOption.CREATE,
                StandardOpenOption.APPEND
            )
        } catch (e: Exception) {
            log.warn("Failed to write log ${path}: ${e.message}")
        }
    }
}
